package cn.qingyun.gis.modules.express.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.qingyun.gis.exception.CommonException;
import cn.qingyun.gis.modules.caronline.entity.CarProofread;
import cn.qingyun.gis.modules.caronline.mapper.CarProofreadMapper;
import cn.qingyun.gis.modules.express.config.Exception.CustomExceptionHandler;
import cn.qingyun.gis.modules.express.constant.ExpressStatus;
import cn.qingyun.gis.modules.express.constant.RedisContant;
import cn.qingyun.gis.modules.express.entity.*;
import cn.qingyun.gis.modules.express.entity.dto.ExportExpressProofreadDto;
import cn.qingyun.gis.modules.express.entity.dto.ExpressInfoTotalDto;
import cn.qingyun.gis.modules.express.entity.dto.ExpressRegionNodeDto;
import cn.qingyun.gis.modules.express.entity.dto.NearbyChannelDto;
import cn.qingyun.gis.modules.express.mapper.*;
import cn.qingyun.gis.modules.express.request.*;
import cn.qingyun.gis.modules.express.response.HwGridByNumResponse;
import cn.qingyun.gis.modules.express.response.RegionResponse;
import cn.qingyun.gis.modules.express.service.IExpressAttachmentService;
import cn.qingyun.gis.modules.express.service.IExpressProofreadService;
import cn.qingyun.gis.modules.express.service.IExpressRegionService;
import cn.qingyun.gis.modules.express.service.IHwRestApiService;
import cn.qingyun.gis.modules.express.util.SyncTool;
import cn.qingyun.gis.modules.init.system.constant.enums.RegionNumPermissionEnum;
import cn.qingyun.gis.modules.init.system.constant.enums.RoleCodeEnum;
import cn.qingyun.gis.modules.init.system.entity.SysLog;
import cn.qingyun.gis.modules.init.system.mapper.SysLogMapper;
import cn.qingyun.gis.modules.init.system.vo.LoginUser;
import cn.qingyun.gis.modules.init.utils.SystemUtil;
import cn.qingyun.gis.modules.scenes.entity.UniAddrRegion;
import cn.qingyun.gis.modules.scenes.service.UniAddrRegionService;
import cn.qingyun.gis.modules.takeaway.entity.TakeawayProofread;
import cn.qingyun.gis.modules.takeaway.mapper.TakeawayProofreadMapper;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * <p>
 * 快递地址勘误 服务实现类
 * </p>
 *
 * @author miyunguo
 * @since 2023-07-27
 */
@Service
@Slf4j
public class ExpressProofreadServiceImpl extends ServiceImpl<ExpressProofreadMapper, ExpressProofread> implements IExpressProofreadService {

    @Resource
    private ExpressProofreadMapper expressProofreadMapper;

    @Resource
    private ExpressInfoMapper expressInfoMapper;

    @Resource
    private ExpressInfoTotalMapper expressInfoTotalMapper;

    @Resource
    private ExpressRegionMapper expressRegionMapper;

    @Resource
    private SysLogMapper sysLogMapper;

    @Resource
    private IExpressAttachmentService iExpressAttachmentService;

    @Resource
    private IExpressRegionService iExpressRegionService;
    @Resource
    private RedissonClient redissonClient;

    @Resource
    private IHwRestApiService hwRestApiService;

    @Resource
    private CustomExceptionHandler customExceptionHandler;
    @Resource
    private OperationLogMapper operationLogMapper;
    @Resource
    private TakeawayProofreadMapper takeawayProofreadMapper;
    @Resource
    private CarProofreadMapper carProofreadMapper;
    @Resource
    private UniAddrRegionService uniAddrRegionService;

    @Value("${qingyun.sso.valid.enabled:false}")
    private Boolean ssoValid;
    @Value("${spring.profiles.active}")
    private String env;

    @Override
    public IPage<ExpressProofread> queryList(ExpressQueryRequest request) {
        //根据网格编码+工号+未勘误（勘误状态=0）+校对类型+修改时间降序匹配查询
        QueryWrapper<ExpressProofread> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotEmpty(request.getLat()) || ObjectUtil.isNotEmpty(request.getLon())) {
            queryWrapper.select("express_proofread.*,grid_id as grid_encoding," + String.format("ROUND(ST_Distance_Sphere(POINT(%s, %s), POINT(express_proofread.lon, express_proofread.lat))/1000,2) AS distance", request.getLon(), request.getLat()))
                    .orderByAsc("distance is null,distance");
        }
        queryWrapper.lambda().eq(ExpressProofread::getKwStatus, ExpressStatus.UN_PROOFED).orderByDesc(ExpressProofread::getUpdateTime);
        String[] gridIdStr = request.getGridId().split(",");
        List<String> gridIdList = Arrays.asList(gridIdStr);

        if (ObjectUtil.isNotEmpty(request.getIsValid())) {
            // 站点有效
            if (request.getIsValid() == 1) {
                queryWrapper.lambda().and(
                        wp -> wp.isNotNull(ExpressProofread::getLat).isNotNull(ExpressProofread::getLon).ne(ExpressProofread::getLon, "").ne(ExpressProofread::getLat, "")
                );
            }
            // 站点无效
            if (request.getIsValid() == 0) {
                queryWrapper.lambda().and(
                        wp -> wp.isNull(ExpressProofread::getLat).or().isNull(ExpressProofread::getLon).or().eq(ExpressProofread::getLon, "").or().eq(ExpressProofread::getLat, "")
                );
            }
        }
        //创建分页对象
        IPage<ExpressProofread> page = new Page<>(request.getPageNum(), request.getPageSize());

        // 根据区域权限进行判定 以及 关键字模糊查询
        if (CharSequenceUtil.isNotEmpty(request.getGridType()) && Boolean.TRUE.equals(RegionNumPermissionEnum.pitchRegion(request.getGridType()))) {
            if (ObjectUtil.isNotEmpty(request.getKeyword())) {
                queryWrapper.lambda().and(lwp -> lwp.like(ExpressProofread::getExpressName, request.getKeyword()).or().like(ExpressProofread::getCompanyAddress, request.getKeyword()).or().like(ExpressProofread::getStationName, request.getKeyword()));
            }
            if (RegionNumPermissionEnum.PROVINCE.name().equals(request.getGridType()) && gridIdList.size() == 1) {
                return expressProofreadMapper.selectPage(page, queryWrapper);
            } else {
                queryWrapper.lambda().and(wp -> wp.in(ExpressProofread::getRegionCityCode, gridIdList).or().in(ExpressProofread::getRegionDistrictsCode, gridIdList).or().in(ExpressProofread::getGridEncoding, gridIdList));
            }
            return expressProofreadMapper.selectPage(page, queryWrapper);
        }
        return new Page<>();
    }

    @Override
    @Transactional
    public String expressProofread(ExpressProofreadRequest request) {
        log.debug("勘误字段：{}" + JSONUtil.toJsonStr(request));
        RLock rlock = redissonClient.getLock(RedisContant.EXPRESS_PROOF_LOCK + request.getId());
        try {
            boolean lockRes = rlock.tryLock(10, TimeUnit.SECONDS);
            if (lockRes) {
                //1.处理express_proofread表
                ExpressProofread proofread = expressProofreadMapper.selectById(request.getId());
                BeanUtil.copyProperties(request, proofread);
                proofread.setKwStatus(ExpressStatus.PROOFED); //更新勘误状态
                if (request.getGridBelongStatus() == 0) { // 优化：若勘误过程，站点不属于本网格，选择应属网格，勘误状态更新为：未勘误
                    proofread.setKwStatus(ExpressStatus.UN_PROOFED);
                    // 自动匹配至应归属网格、应归属区县
                    proofread.setGridName(request.getBelongGrid());
                    proofread.setGridEncoding(request.getBelongGridCode());
                    proofread.setRegionDistricts(request.getBelongCounty());
                    proofread.setRegionDistrictsCode(request.getBelongCountyCode());
                    // 进行日志记录入库
                    OperationLog operationLog = OperationLog.builder()
                            .logAccount(request.getKwPhone())
                            .operationId(request.getId())
                            .logType(0) // 0:应属网格操作
                            .operateType(0)  //0:快递
                            .createTime(DateUtil.date()).build();
                    operationLogMapper.insert(operationLog);
                }
                proofread.setUpdateTime(DateUtil.date());//更新修改(勘误)时间
                expressProofreadMapper.updateById(proofread);

                //2.处理express_info表
                ExpressInfo res = expressInfoMapper.selectOne(new LambdaQueryWrapper<ExpressInfo>().eq(ExpressInfo::getExpressProofreadId, request.getId()));
                ExpressInfo info = new ExpressInfo();
                if (ObjectUtil.isEmpty(res)) {
                    BeanUtil.copyProperties(request, info);
                    info.setId(null);
                    info.setExpressProofreadId(request.getId());
                    info.setCreateTime(DateUtil.date()); // 初次勘误时间记录
                    info.setUpdateTime(DateUtil.date()); // 初次修改时间
                    expressInfoMapper.insert(info);
                } else {
                    BeanUtil.copyProperties(request, info);
                    info.setId(res.getId());
                    info.setExpressProofreadId(request.getId());
                    info.setUpdateTime(DateUtil.date()); //勘误修改时间记录
                    expressInfoMapper.updateById(info);
                }
                //3.图片上传
                iExpressAttachmentService.upload(request.getPictureList(), request.getId());
                return "勘误成功";
            }
            return "系统繁忙，请稍后再试";

        } catch (Exception e) {
            throw new CommonException("勘误失败");
        } finally {
            rlock.unlock();
        }
    }

    @Override
    public IPage<ImportExpressExcel20230727> exportExpressExcelBatch(Page<ImportExpressExcel20230727> page) {
        return expressProofreadMapper.exportExpressExcelBatch(page);
    }

    @Override
    public IPage<ExpressProofread> queryUnProofread(ExpressQueryRequest request) {
        //1. 根据工号返回网格列表
        //1.1 获取token
        HwGetTokenRequest getTokenRequest = new HwGetTokenRequest();
        getTokenRequest.setGrantType("client_credentials");
        getTokenRequest.setClientId("202309261052075951000019");
        getTokenRequest.setClientSecret("7bd16d81fefddcba523e85481095b876");
        getTokenRequest.setTokenType("JWT");
        String token = hwRestApiService.getToken(getTokenRequest);
        //1.2 根据token+工号获取网格列表
        HwGetGridIdRequest getGridIdRequest = new HwGetGridIdRequest();
        getGridIdRequest.setCrmAccount(request.getKwPhone());
        getGridIdRequest.setToken(token);
        getGridIdRequest.setType("3");
        JSONObject jsonObject = hwRestApiService.getGridByAccount(getGridIdRequest);
        //1.3 todo
        //根据网格编码+工号+未勘误（勘误状态=0）+校对类型+修改时间降序匹配查询
        QueryWrapper<ExpressProofread> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ExpressProofread::getKwStatus, ExpressStatus.UN_PROOFED).orderByDesc(ExpressProofread::getUpdateTime);
        String[] gridIdStr = request.getGridId().split(",");
        List<String> gridIdList = Arrays.asList(gridIdStr);
        queryWrapper.and(w -> gridIdList.forEach(i -> w.eq("grid_id", i).or()));
        //创建分页对象
        IPage<ExpressProofread> page = new Page<>(request.getPageNum(), request.getPageSize());
        return expressProofreadMapper.selectPage(page, queryWrapper);
    }

    @Override
    public TreeMap<String, String> areaPermissionByNum(TreeMap<String, String> decryptedMap) {
        /**
         * 一个工号可能有多个角色，不同角色权限可能不是同一级别
         * */
        String crmAccount = decryptedMap.get("telNum"); //获取工号
        String gridType = "";
        String gridIds = "";
        HwGetGridIdRequest request = new HwGetGridIdRequest();
        request.setType("3"); // 暂时只支持 type入参为3的情况
        request.setCrmAccount(crmAccount);
        List<HwGridByNumResponse> responseList = hwRestApiService.getGridByAccountTest(request);
        if (CollUtil.isNotEmpty(responseList)) {
            // 根据网格编码进行去重
            List<HwGridByNumResponse> newResponseList = responseList.stream().filter(item -> ObjectUtil.isNotNull(item.getAreaCode())).collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(HwGridByNumResponse::getAreaCode))), ArrayList::new));
            // 网格匹配不为空
            if (!newResponseList.isEmpty()) {
                gridType = RegionNumPermissionEnum.UN_PROVINCE.name(); // 默认为非省级权限工号
                List<String> areaCodeList = new ArrayList<>();
                // 遍历业务区域列表
                for (HwGridByNumResponse response : newResponseList) {
                    if ("SD".equals(response.getAreaCode())) {
                        gridType = RegionNumPermissionEnum.PROVINCE.name(); //返回省份编码
                        areaCodeList.clear();
                        areaCodeList.add(response.getAreaCode());
                        break;
                    }
                    areaCodeList.add(response.getAreaCode());
                }
                gridIds = String.join(",", areaCodeList);
            }
        }
        TreeMap<String, String> resultMap = Maps.newTreeMap();
        resultMap.put("gridType", gridType); //传入权限区域类型 province un_province
        resultMap.put("gridId", gridIds);
        resultMap.put("telNum", crmAccount);
        resultMap.put("username", decryptedMap.get("username"));
        resultMap.put("channelCode", decryptedMap.get("channelCode"));
        resultMap.put("userId", decryptedMap.get("userid"));
        return resultMap;
    }

    @Override
    public TreeMap<String, String> areaYsPermissionByNum(String telNum) {
        /**
         * 一个工号可能有多个角色，不同角色权限可能不是同一级别
         * */
        String gridType = "";
        String gridIds = "";
        String isFailed = "FALSE";
        HwGetGridIdRequest request = new HwGetGridIdRequest();
        request.setType("3"); // 暂时只支持 type入参为3的情况
        request.setCrmAccount(telNum);
        List<HwGridByNumResponse> responseList = hwRestApiService.getGridByAccountTest(request);
        if (CollUtil.isNotEmpty(responseList)) {
            // 根据网格编码进行去重
            List<HwGridByNumResponse> newResponseList = responseList.stream().filter(item -> ObjectUtil.isNotNull(item.getAreaCode())).collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(HwGridByNumResponse::getAreaCode))), ArrayList::new));
            // 网格匹配不为空
            if (!newResponseList.isEmpty()) {
                gridType = RegionNumPermissionEnum.UN_PROVINCE.name(); // 默认为非省级权限工号
                List<String> areaCodeList = new ArrayList<>();
                // 遍历业务区域列表
                for (HwGridByNumResponse response : newResponseList) {
                    if ("SD".equals(response.getAreaCode())) {
                        gridType = RegionNumPermissionEnum.PROVINCE.name(); //返回省份编码
                        areaCodeList.clear();
                        areaCodeList.add(response.getAreaCode());
                        isFailed = "TRUE";
                        break;
                    }

                    if (response.getAllParentCode().contains("SD.LI") || response.getAllParentCode().contains("SD.LA.0d")) { // 开放 临沂地市权限
                        isFailed = "TRUE";

                    }
                    areaCodeList.add(response.getAreaCode());
                }
                gridIds = String.join(",", areaCodeList);
            }
        }
        TreeMap<String, String> resultMap = Maps.newTreeMap();
        resultMap.put("gridType", gridType); //传入权限区域类型 province un_province
        resultMap.put("gridId", gridIds);
        resultMap.put("telNum", telNum);
        resultMap.put("isFailed", isFailed); // 是否开启权限
        return resultMap;
    }

    @Override
    public IPage<ExportExpressProofreadDto> queryDetailList(Page<ExportExpressProofreadDto> page, Integer kwStatue, String regionCityCode) {
        return expressInfoTotalMapper.selectExpressProofreadTotal(page, null, regionCityCode);
    }

    /**
     * 对未勘误站点进行网格每日匹配
     */
    @Override
    @Transactional
    public void matchGrid() {


        AtomicInteger n = new AtomicInteger();
        // 获取微网格级别业务区划数据
        LambdaQueryWrapper<ExpressRegion> miroGridWrapper = new QueryWrapper<ExpressRegion>().lambda().eq(ExpressRegion::getLevel, "5").ne(ExpressRegion::getGeometry, "");
        List<ExpressRegion> miroGridTotal = iExpressRegionService.list(miroGridWrapper);
        // 获取网格级别业务区划数据
        LambdaQueryWrapper<ExpressRegion> gridWrapper = new QueryWrapper<ExpressRegion>().lambda().eq(ExpressRegion::getLevel, "4").ne(ExpressRegion::getGeometry, "");
        List<ExpressRegion> gridTotal = iExpressRegionService.list(gridWrapper);
        // 获取区县级别业务区划数据
        LambdaQueryWrapper<ExpressRegion> districtsWrapper = new QueryWrapper<ExpressRegion>().lambda().eq(ExpressRegion::getLevel, "3").ne(ExpressRegion::getGeometry, "");
        List<ExpressRegion> districtsTotal = iExpressRegionService.list(districtsWrapper);
        // 获取地市级别业务区划数据
        LambdaQueryWrapper<ExpressRegion> cityWrapper = new QueryWrapper<ExpressRegion>().lambda().eq(ExpressRegion::getLevel, "2").ne(ExpressRegion::getGeometry, "");
        List<ExpressRegion> cityTotal = iExpressRegionService.list(cityWrapper);

        // 计算未勘误网格总条数
        QueryWrapper<ExpressProofread> expressProofreadQueryWrapper = new QueryWrapper<>();
        expressProofreadQueryWrapper.lambda().eq(ExpressProofread::getKwStatus, 0);
        int count = this.count(expressProofreadQueryWrapper);
        int pages = (count / 1000) + 1;
        // 根据数据总量划分数据块并启动多线程
        long start = System.currentTimeMillis();
        String message = null; // 日志内容
        SyncTool.doSync(pages, i -> {

            Page<ExpressProofread> page = new Page<>(i, 1000);
            List<ExpressProofread> expressProofreads = this.page(page, expressProofreadQueryWrapper).getRecords();
            List<ExpressProofread> updateRecords = Lists.newArrayList();
            for (ExpressProofread expressData : expressProofreads) {
                try {
                    double lon = 0;
                    double lat = 0;
                    // 如果原始经纬度不为空
                    if (ObjectUtil.isNotEmpty(expressData.getLon()) && ObjectUtil.isNotEmpty(expressData.getLat())) {
                        lon = expressData.getLon().doubleValue();
                        lat = expressData.getLat().doubleValue();
                    }
                    // 如果勘误经纬度不为空
                    if (ObjectUtil.isNotEmpty(expressData.getKwLon()) && ObjectUtil.isNotEmpty(expressData.getKwLat())) {
                        lon = expressData.getKwLon().doubleValue();
                        lat = expressData.getKwLat().doubleValue();
                    }

                    // 需要匹配经纬度都不为0
                    if ((lat != 0) && (lon != 0)) {
                        // 创建点对象
                        Point point = new GeometryFactory().createPoint(new Coordinate(expressData.getLon().doubleValue(), expressData.getLat().doubleValue()));
                        Geometry geometry = null;
                        // 1.进行微网格匹配
                        for (ExpressRegion miroGridData : miroGridTotal) {
                            // 创建面对象

                            geometry = new WKTReader().read(miroGridData.getGeometry());
                            // 微网格匹配成功
                            if (geometry.contains(point)) {
                                expressData.setMicroGridId(miroGridData.getCode());
                                expressData.setMicroGridName(miroGridData.getName());
                                break;
                            }
                        }
                        // 2.进行网格匹配
                        for (ExpressRegion gridData : gridTotal) {
                            // 创建面对象

                            geometry = new WKTReader().read(gridData.getGeometry());
                            // 网格匹配成功
                            if (geometry.contains(point)) {
                                expressData.setGridEncoding(gridData.getCode());
                                expressData.setGridName(gridData.getName());
                                break;
                            }
                        }
                        // 3.进行区县匹配
                        for (ExpressRegion disData : districtsTotal) {
                            // 创建面对象

                            geometry = new WKTReader().read(disData.getGeometry());
                            // 匹配区县成功
                            if (geometry.contains(point)) {
                                expressData.setRegionDistrictsCode(disData.getCode());
                                expressData.setRegionDistricts(disData.getName());
                                break;
                            }

                        }
                        // 4.进行地市匹配
                        for (ExpressRegion cityData : cityTotal) {
                            // 创建面对象
                            geometry = new WKTReader().read(cityData.getGeometry());
                            // 匹配地市成功
                            if (geometry.contains(point)) {
                                expressData.setRegionCityCode(cityData.getCode());
                                expressData.setRegionCity(cityData.getName());
                                break;
                            }

                        }
                    }
                    synchronized (this) {
                        n.incrementAndGet();
                        log.debug(String.format("=========== 当前匹配进度为%s / %s ===========", n, count));
                    }
                } catch (ParseException e) {
                    customExceptionHandler.handleException(String.format("快递站点-%s,自动入格失败！|报错：%s", expressData.getStationName(), e.getMessage()), start);
                }
                // 如果站点经纬度都不为空或空字符串
                updateRecords.add(expressData);
            }

            // 批量导入匹配之后数据
            this.updateBatchById(updateRecords);

        });
        message = "网格匹配-快递勘误表匹配入格成功";
        SysLog sysLog = new SysLog();
        // 导入生产日志
        long finish = System.currentTimeMillis();
        sysLog.setLogContent(message);
        sysLog.setCreateTime(DateUtil.date());
        sysLog.setLogType(3); //定时任务日志类型
        sysLog.setCreateBy("system");
        sysLog.setUserid("匹配任务");
        sysLog.setCostTime(finish - start);
        sysLogMapper.insert(sysLog);
    }

    @Override
    public PermRegionNode regionList(String telNum) {
        log.debug("根据工号查询级联权限区域-入参工号：{}", telNum);
        List<HwGridByNumResponse> responseList = Lists.newArrayList();
        if (ssoValid.equals(Boolean.TRUE)) {
            // 调用华为直连网格 - 根据工号返回相应业务区域
            HwGetGridIdRequest request = new HwGetGridIdRequest();
            request.setCrmAccount(telNum);
            request.setType("3");
            responseList = hwRestApiService.getGridByAccountTest(request);
            log.debug("调用直连华为地址获取权限区域列表-{}", JSONUtil.toJsonStr(responseList));
        }
        else {
            responseList.add(HwGridByNumResponse.builder()
                    .allParentCode("SD,SD.LB,SD.LB.08,532.0009.006")
                    .areaCode("532.0009.006")
                    .fullName("山东-青岛-开发区-辛安社区网格")
                    .areaName("辛安社区网格").build());
//            responseList.add(HwGridByNumResponse.builder()
//                    .allParentCode("SD,SD.LA,SD.LA.02,531.0003.2111")
//                    .areaCode("531.0003.2111")
//                    .fullName("山东-济南-章丘区-官庄乡镇网格")
//                    .areaName("官庄乡镇网格").build());
        }
        if (ObjectUtil.isNotEmpty(responseList)) {
            // 根据网格编码进行去重
            List<HwGridByNumResponse> newResponseList = responseList.stream().filter(item -> StringUtils.isNotEmpty(item.getAreaCode()) &&
                    StringUtils.isNotEmpty(item.getAllParentCode()) && StringUtils.isNotEmpty(item.getFullName())).collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(HwGridByNumResponse::getAreaCode))), ArrayList::new));
            // 处理接口返回数据
            List<String> addressList = Lists.newArrayList();
            List<String> codeList = Lists.newArrayList();
            if (CollectionUtils.isEmpty(newResponseList)){
                return new PermRegionNode();
            }
            for (HwGridByNumResponse response : newResponseList) {
                addressList.add(response.getFullName());
                codeList.add(response.getAllParentCode());
            }
            //
            List<RegionLevel> items = Lists.newArrayList();
            for (int index = 0; index < addressList.size(); index++) {
                String[] addrSplit = addressList.get(index).split("-");
                String[] codeSplit = codeList.get(index).split(",");
                if (addrSplit.length != codeSplit.length) {
                    throw new CommonException("解析接口-区域编码与名称映射出错！");
                }
                RegionLevel item = new RegionLevel();
                if (addrSplit.length == 1) {
                    item.setProvince(addrSplit[0] + "|" + codeSplit[0]);
                } else if (addrSplit.length == 2) {
                    item.setProvince(addrSplit[0] + "|" + codeSplit[0]);
                    item.setCity(addrSplit[1] + "|" + codeSplit[1]);
                } else if (addrSplit.length == 3) {
                    item.setProvince(addrSplit[0] + "|" + codeSplit[0]);
                    item.setCity(addrSplit[1] + "|" + codeSplit[1]);
                    item.setDistricts(addrSplit[2] + "|" + codeSplit[2]);
                } else if (addrSplit.length == 4) {
                    item.setProvince(addrSplit[0] + "|" + codeSplit[0]);
                    item.setCity(addrSplit[1] + "|" + codeSplit[1]);
                    item.setDistricts(addrSplit[2] + "|" + codeSplit[2]);
                    item.setGrid(addrSplit[3] + "|" + codeSplit[3]);
                }
                items.add(item);
            }
            //
            List<PermRegionNode> provinces = Lists.newArrayList();
            items.stream().collect(Collectors.groupingBy(RegionLevel::getProvince)).forEach((provinceName, cityList) -> {
                PermRegionNode provinceTree = new PermRegionNode();
                provinceTree.setName(provinceName.split("\\|")[0]);
                provinceTree.setCode(provinceName.split("\\|")[1]);
                provinceTree.setGridType(RegionNumPermissionEnum.PROVINCE.name());
                List<PermRegionNode> cities = Lists.newArrayList();
                cityList.stream().filter(item -> CharSequenceUtil.isNotBlank(item.getCity())).collect(Collectors.groupingBy(RegionLevel::getCity)).forEach((cityName, countyList) -> {
                    PermRegionNode cityTree = new PermRegionNode();
                    cityTree.setName(cityName.split("\\|")[0]);
                    cityTree.setCode(cityName.split("\\|")[1]);
                    cityTree.setGridType(RegionNumPermissionEnum.UN_PROVINCE.name());
                    List<PermRegionNode> counties = Lists.newArrayList();
                    countyList.stream().filter(item -> CharSequenceUtil.isNotBlank(item.getDistricts())).collect(Collectors.groupingBy(RegionLevel::getDistricts)).forEach((countyName, gridList) -> {
                        PermRegionNode countyTree = new PermRegionNode();
                        countyTree.setName(countyName.split("\\|")[0]);
                        countyTree.setCode(countyName.split("\\|")[1]);
                        countyTree.setGridType(RegionNumPermissionEnum.UN_PROVINCE.name());
                        List<PermRegionNode> girds = Lists.newArrayList();
                        gridList.stream().filter(item -> CharSequenceUtil.isNotBlank(item.getGrid())).collect(Collectors.groupingBy(RegionLevel::getGrid)).forEach((gridName, _item) -> {
                            PermRegionNode girdTree = new PermRegionNode();
                            girdTree.setName(gridName.split("\\|")[0]);
                            girdTree.setCode(gridName.split("\\|")[1]);
                            girdTree.setGridType(RegionNumPermissionEnum.UN_PROVINCE.name());
                            girdTree.setState(1);
                            girds.add(girdTree);
                        });
                        countyTree.setChildNodes(girds);
                        countyTree.setState(ObjectUtil.isNotEmpty(girds) ? 0 : 1);
                        counties.add(countyTree);

                    });
                    cityTree.setChildNodes(counties);
                    cityTree.setState(ObjectUtil.isNotEmpty(counties) ? 0 : 1);
                    cities.add(cityTree);
                });
                provinceTree.setChildNodes(cities);
                provinceTree.setState(ObjectUtil.isNotEmpty(cities) ? 0 : 1);
                provinces.add(provinceTree);
            });
            // 根据地市属性进行排序
            provinces.get(0).getChildNodes().sort(Comparator.comparing(PermRegionNode::getCode));
            log.debug("调用regionList接口返回：{}", JSON.toJSONString(provinces.get(0)));
            return provinces.get(0);
        }
        log.debug("工号查询级联权限区域接口调用结束");
        log.warn("responseList为空，返回空权限");
        return new PermRegionNode();
    }

    @Override
    public List<ExpressRegionNodeDto> sonRegionList(String code) {
        QueryWrapper<UniAddrRegion> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().select(UniAddrRegion::getCode, UniAddrRegion::getName,UniAddrRegion::getLevel).eq(UniAddrRegion::getParentCode, code).ne(UniAddrRegion::getState,-1);
        List<UniAddrRegion> expressRegions = uniAddrRegionService.list(queryWrapper);
        List<ExpressRegionNodeDto> expressRegionNodes = Lists.newArrayList();
        for (UniAddrRegion data : expressRegions) {
            ExpressRegionNodeDto node = new ExpressRegionNodeDto();
            BeanUtil.copyProperties(data, node);
            node.setGridType(RegionNumPermissionEnum.UN_PROVINCE.name()); // 调用此接口返回节点区域等级为非省级
            node.setState("1");
            if (data.getLevel()!=null && data.getLevel()==4){
                String name = node.getName();
                String[] parts = name.split("-");
                String result = parts.length > 1 ? parts[1] : name;
                node.setName(result);
            }
            if (!node.getName().contains("政企") && !node.getName().contains("校园") && !node.getName().contains("虚拟网格") && !node.getName().contains("商企网格")){
                expressRegionNodes.add(node);
            }
        }
        expressRegionNodes.sort(Comparator.comparing(ExpressRegionNodeDto::getCode));
        return expressRegionNodes;
    }

    @Override
    @Transactional
    public void matchBelongGrid() {
        // 获取区县列表
        List<ExpressRegion> districtsRegions = expressRegionMapper.selectList(new QueryWrapper<ExpressRegion>().lambda().eq(ExpressRegion::getLevel, 3));
        // 获取网格列表
        List<ExpressRegion> gridRegions = expressRegionMapper.selectList(new QueryWrapper<ExpressRegion>().lambda().eq(ExpressRegion::getLevel, 4));


        // 获取已经勘误 +  是否归属本网格 站点信息
        List<ExpressInfoTotalDto> datas = expressInfoTotalMapper.selectExpressTotal();
        List<ExpressProofread> expressProofreads = Lists.newArrayList();
        for (ExpressInfoTotalDto data : datas) {
            // 调用区县列表
            for (ExpressRegion districts : districtsRegions) {
                // 获取区县编码
                if (districts.getName().equals(data.getBelongCounty())) {
                    data.setBelongCountyCode(districts.getCode());
                    break;
                }
            }
            // 调用网格列表
            for (ExpressRegion grid : gridRegions) {
                // 获取网格编码
                if (grid.getName().equals(data.getBelongGrid())) {
                    data.setBelongGridCode(grid.getCode());
                    break;
                }
            }

            // 将应属区县+编码、应属网格+编码 进行快递站点匹配
            if (ObjectUtil.isNotEmpty(data.getBelongGridCode()) && ObjectUtil.isNotEmpty(data.getBelongCountyCode())) {
                ExpressProofread expressProofread = new ExpressProofread();
                expressProofread.setId(data.getId());
                expressProofread.setGridName(data.getBelongGrid());
                expressProofread.setGridEncoding(data.getBelongGridCode());
                expressProofread.setRegionDistricts(data.getBelongCounty());
                expressProofread.setRegionDistrictsCode(data.getBelongCountyCode());
                expressProofreads.add(expressProofread);
            }

        }
        this.updateBatchById(expressProofreads); // 批量更新
    }

    @Override
    public IPage<NearbyChannelDto> nearbyChannel(NearbyChannelRequest request) {
        if (CharSequenceUtil.isEmpty(request.getGridType()) || Boolean.FALSE.equals(RegionNumPermissionEnum.pitchRegion(request.getGridType()))) {
            throw new CommonException("区域权限类型输入为空或不符合规范");
        }
        if (ObjectUtil.isEmpty(request.getLat()) || ObjectUtil.isEmpty(request.getLon())) {
            throw new CommonException("实时经纬度不能为空");
        }

        List<NearbyChannelDto> res = Lists.newArrayList();

        // 1.查询快递
        QueryWrapper<ExpressProofread> queryWrapper = new QueryWrapper<>();
        // 保证站点有效
        queryWrapper.lambda().and(
                wp -> wp.isNotNull(ExpressProofread::getLat).isNotNull(ExpressProofread::getLon).ne(ExpressProofread::getLon, "").ne(ExpressProofread::getLat, "")
        );
        // 关键字查询
        if (ObjectUtil.isNotEmpty(request.getKeyword())) {
            queryWrapper.lambda().and(lwp -> lwp.like(ExpressProofread::getExpressName, request.getKeyword()).or().like(ExpressProofread::getCompanyAddress, request.getKeyword()).or().like(ExpressProofread::getStationName, request.getKeyword()));
        }

        if (request.getStatus() == 0) {
            queryWrapper.select("id,express_name,station_name,company_address,lon,lat," + String.format("ROUND(ST_Distance_Sphere(POINT(%s, %s), POINT(lon, lat))/1000,2) AS distance", request.getLon(), request.getLat()))
                    .apply(String.format("ROUND(ST_Distance_Sphere(POINT(%s, %s), POINT(lon, lat))/1000,2) <= 1.00", request.getLon(), request.getLat()));
            queryWrapper.lambda().eq(ExpressProofread::getKwStatus, 0);
        }
        if (request.getStatus() == 1) {
            queryWrapper.select("id,express_name,station_name,company_address,kw_lon as lon,kw_lat as lat," + String.format("ROUND(ST_Distance_Sphere(POINT(%s, %s), POINT(lon, lat))/1000,2) AS distance", request.getLon(), request.getLat()))
                    .apply(String.format("ROUND(ST_Distance_Sphere(POINT(%s, %s), POINT(kw_lon, kw_lat))/1000,2) <= 1.00", request.getLon(), request.getLat()));
            queryWrapper.lambda().eq(ExpressProofread::getKwStatus, 1);
        }
        // 根据区域权限进行判定
        List<String> gridIdList = Arrays.asList(request.getGridId().split(","));
        if (RegionNumPermissionEnum.UN_PROVINCE.name().equals(request.getGridType())) {
            queryWrapper.lambda().and(wp -> wp.in(ExpressProofread::getRegionCityCode, gridIdList).or().in(ExpressProofread::getRegionDistrictsCode, gridIdList).or().in(ExpressProofread::getGridEncoding, gridIdList));
        }
        List<ExpressProofread> expressProofreads = expressProofreadMapper.selectList(queryWrapper);

        // 存在1Km站点
        if (!expressProofreads.isEmpty()) {
            for (ExpressProofread data : expressProofreads) {
                NearbyChannelDto express = NearbyChannelDto.builder()
                        .id(data.getId())
                        .name(data.getStationName())
                        .address(data.getCompanyAddress())
                        .type(data.getExpressName())
                        .lon(data.getLon())
                        .lat(data.getLat())
                        .typeCode(0)
                        .distance(data.getDistance())
                        .build();
                res.add(express);
            }
        }

        // 2.查询外卖
        QueryWrapper<TakeawayProofread> takeWrapper = new QueryWrapper<>();

        // 关键字查询
        if (ObjectUtil.isNotEmpty(request.getKeyword())) {
            takeWrapper.lambda().and(
                    lwp -> lwp.like(TakeawayProofread::getPoiAddress, request.getKeyword()).or().like(TakeawayProofread::getPoiName, request.getKeyword())
            );
        }

        if (request.getStatus() == 0) {
            takeWrapper.select("id,poi_name,poi_address,type_two,lon,lat," + String.format("ROUND(ST_Distance_Sphere(POINT(%s, %s), POINT(lon, lat))/1000,2) AS distance", request.getLon(), request.getLat()))
                    .apply(String.format("ROUND(ST_Distance_Sphere(POINT(%s, %s), POINT(lon, lat))/1000,2) <= 1.00", request.getLon(), request.getLat()));

            takeWrapper.lambda().eq(TakeawayProofread::getKwStatus, 0);
        }
        if (request.getStatus() == 1) {
            takeWrapper.select("id,poi_name,poi_address,type_two,kw_lon as lon,kw_lat as lat," + String.format("ROUND(ST_Distance_Sphere(POINT(%s, %s), POINT(lon, lat))/1000,2) AS distance", request.getLon(), request.getLat()))
                    .apply(String.format("ROUND(ST_Distance_Sphere(POINT(%s, %s), POINT(kw_lon, kw_lat))/1000,2) <= 1.00", request.getLon(), request.getLat()));

            takeWrapper.lambda().eq(TakeawayProofread::getKwStatus, 1);
        }
        // 选定区域权限
        if (RegionNumPermissionEnum.UN_PROVINCE.name().equals(request.getGridType())) {
            takeWrapper.lambda().and(wp -> wp.in(TakeawayProofread::getRegionCityCode, gridIdList).or().in(TakeawayProofread::getRegionDistrictsCode, gridIdList).or().in(TakeawayProofread::getGridId, gridIdList));
        }

        List<TakeawayProofread> takeawayProofreads = takeawayProofreadMapper.selectList(takeWrapper);
        if (!takeawayProofreads.isEmpty()) {
            for (TakeawayProofread data : takeawayProofreads) {
                NearbyChannelDto takeaway = NearbyChannelDto.builder()
                        .id(data.getId())
                        .name(data.getPoiName())
                        .address(data.getPoiAddress())
                        .type(data.getTypeTwo())
                        .lon(data.getLon())
                        .lat(data.getLat())
                        .typeCode(1)
                        .distance(data.getDistance())
                        .build();
                res.add(takeaway);
            }
        }

        // 3.查询网约车
        QueryWrapper<CarProofread> carWrapper = new QueryWrapper<>();

        // 关键字查询
        if (ObjectUtil.isNotEmpty(request.getKeyword())) {
            carWrapper.lambda().and(lwp -> lwp.like(CarProofread::getPoiAddress, request.getKeyword()).or().like(CarProofread::getPoiName, request.getKeyword()));
        }

        if (request.getStatus() == 0) {
            carWrapper.select("id,poi_name,poi_address,type_two,lon,lat," + String.format("ROUND(ST_Distance_Sphere(POINT(%s, %s), POINT(lon, lat))/1000,2) AS distance", request.getLon(), request.getLat()))
                    .apply(String.format("ROUND(ST_Distance_Sphere(POINT(%s, %s), POINT(lon, lat))/1000,2) <= 1.00", request.getLon(), request.getLat()));
            carWrapper.lambda().eq(CarProofread::getKwStatus, 0);
        }
        if (request.getStatus() == 1) {
            carWrapper.select("id,poi_name,poi_address,type_two,kw_lon as lon,kw_lat as lat," + String.format("ROUND(ST_Distance_Sphere(POINT(%s, %s), POINT(lon, lat))/1000,2) AS distance", request.getLon(), request.getLat()))
                    .apply(String.format("ROUND(ST_Distance_Sphere(POINT(%s, %s), POINT(kw_lon, kw_lat))/1000,2) <= 1.00", request.getLon(), request.getLat()));
            carWrapper.lambda().eq(CarProofread::getKwStatus, 1);
        }
        // 区域权限判定
        if (RegionNumPermissionEnum.UN_PROVINCE.name().equals(request.getGridType())) {
            carWrapper.lambda().and(wp -> wp.in(CarProofread::getRegionCityCode, gridIdList).or().in(CarProofread::getRegionDistrictsCode, gridIdList).or().in(CarProofread::getGridId, gridIdList));
        }
        List<CarProofread> carProofreads = carProofreadMapper.selectList(carWrapper);

        if (!carProofreads.isEmpty()) {
            for (CarProofread data : carProofreads) {
                NearbyChannelDto takeaway = NearbyChannelDto.builder()
                        .id(data.getId())
                        .name(data.getPoiName())
                        .address(data.getPoiAddress())
                        .type(data.getTypeTwo())
                        .lon(data.getLon())
                        .lat(data.getLat())
                        .typeCode(2)
                        .distance(data.getDistance())
                        .build();
                res.add(takeaway);
            }
        }
        // 根据 distance 进行升序
        res.stream().sorted(Comparator.comparing(NearbyChannelDto::getDistance)).collect(Collectors.toList());
        Page<NearbyChannelDto> page = new Page<>(request.getPageNum(), request.getPageSize());
        page.setTotal(res.size());
        int startIndex = (request.getPageNum() - 1) * request.getPageSize();
        int endIndex = Math.min(startIndex + request.getPageSize(), res.size());
        page.setRecords(res.subList(startIndex, endIndex));
        return page;
    }

    @Override
    public Object queryExpressById(QueryRequest request) {
        if (request.getStatus() == 0) {
            QueryWrapper<ExpressProofread> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(ExpressProofread::getKwStatus, 0).eq(ExpressProofread::getId, request.getId());
            return expressProofreadMapper.selectOne(queryWrapper);
        }
        if (request.getStatus() == 1) {
            return expressInfoTotalMapper.queryProofreadById(request.getId());
        }
        return "根据id查询快递失败";
    }

    @Override
    public Object queryTakeawayById(QueryRequest request) {
        if (request.getStatus() == 0) {
            QueryWrapper<TakeawayProofread> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(TakeawayProofread::getKwStatus, 0).eq(TakeawayProofread::getId, request.getId());
            return takeawayProofreadMapper.selectOne(queryWrapper);
        }
        if (request.getStatus() == 1) {
            return takeawayProofreadMapper.queryProofreadById(request.getId());
        }
        return "根据id查询外卖失败";
    }

    @Override
    public Object queryCarById(QueryRequest request) {
        if (request.getStatus() == 0) {
            QueryWrapper<CarProofread> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(CarProofread::getKwStatus, 0).eq(CarProofread::getId, request.getId());
            return carProofreadMapper.selectOne(queryWrapper);
        }
        if (request.getStatus() == 1) {
            return carProofreadMapper.queryProofreadById(request.getId());
        }
        return "根据id查询外卖失败";
    }

    @Override
    public List<Tree<String>> getRegionList() {

        List<HwGridByNumResponse> responseList = Lists.newArrayList();
        if (ssoValid.equals(Boolean.TRUE) || ("test".equals(env) && !Objects.requireNonNull(SystemUtil.getCurrentUser()).getUsername().equals("root"))) {
            LoginUser currentUser = SystemUtil.getCurrentUser();
            if (ObjectUtil.isNull(currentUser)) {
                throw new CommonException("解析用户失败");
            }
            // 调用华为直连网格 - 根据工号返回相应业务区域
            HwGetGridIdRequest request = new HwGetGridIdRequest();
            request.setCrmAccount(currentUser.getUsername());
            request.setType("3");
            responseList = hwRestApiService.getGridByAccountTest(request);
        } else {
            responseList.add(HwGridByNumResponse.builder()
                    .allParentCode("SD")
                    .areaCode("SD")
                    .fullName("山东")
                    .areaName("天桥").build());
        }

        if (Objects.isNull(responseList)) {
            throw new CommonException("获取人员权限失败");
        }
        List<RegionResponse> allList = new ArrayList<>();
        List<HwGridByNumResponse> sortPermissions = responseList.stream().sorted(Comparator.comparingInt(item -> item.getAllParentCode().split(",").length)).collect(Collectors.toList());
        List<String> allCode = new ArrayList<>();
        for (HwGridByNumResponse datum : sortPermissions) {
            String[] areaCode = datum.getAllParentCode().split(",");
            String[] areaName = datum.getFullName().split("-");
            if (!Objects.equals(areaCode.length, areaName.length)) {
                throw new CommonException("解析接口-区域编码与名称映射出错！");
            }
            //allParentCode和fullName为空，跳过该值处理
            if (StringUtils.isEmpty(datum.getAllParentCode())||StringUtils.isEmpty(datum.getFullName())){
                log.debug("空值跳过！");
                continue;
            }
            List<RegionResponse> list = new ArrayList<>();
            //如果是省级权限
            if (areaCode.length == 1) {
                QueryWrapper<UniAddrRegion> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().select(UniAddrRegion::getCode, UniAddrRegion::getName, UniAddrRegion::getParentCode).eq(UniAddrRegion::getLevel, 1).or().eq(UniAddrRegion::getLevel, 2).or().eq(UniAddrRegion::getLevel, 3).orderByAsc(UniAddrRegion::getLevel);
                List<UniAddrRegion> gridList = uniAddrRegionService.list(queryWrapper);
                list = BeanUtil.copyToList(gridList, RegionResponse.class);
                list.stream()
                        .filter(region -> region.getCode().equals("SD"))
                        .forEach(region -> {
                            region.setParentCode("0");
                        });
                allCode.add(datum.getAllParentCode());
            } else if (areaCode.length == 2) {//市级权限
                QueryWrapper<UniAddrRegion> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().select(UniAddrRegion::getCode, UniAddrRegion::getName, UniAddrRegion::getParentCode).eq(UniAddrRegion::getParentCode, datum.getAreaCode()).or().eq(UniAddrRegion::getCode, datum.getAreaCode());
                List<UniAddrRegion> gridList = uniAddrRegionService.list(queryWrapper);
                QueryWrapper<UniAddrRegion> sdWrapper = new QueryWrapper<>();
                sdWrapper.lambda().select(UniAddrRegion::getCode, UniAddrRegion::getName, UniAddrRegion::getParentCode).eq(UniAddrRegion::getLevel, 1);
                UniAddrRegion sd = uniAddrRegionService.getBaseMapper().selectOne(sdWrapper);
                RegionResponse sdRegion = new RegionResponse();
                BeanUtils.copyProperties(sd, sdRegion);
                sdRegion.setClick(false);
                sdRegion.setParentCode("0");
                list = BeanUtil.copyToList(gridList, RegionResponse.class);
                list.add(sdRegion);
                allCode.add(datum.getAllParentCode());
            } else if (areaCode.length == 3) {
                for (int i = 0; i < areaCode.length; i++) {
                    RegionResponse region = new RegionResponse();
                    if (i == 0) {
                        region.setCode(areaCode[i]).setParentCode("0").setName(areaName[i]).setParentName("").setClick(false);
                    } else if (i == 1) {
                        region.setCode(areaCode[i]).setParentCode(areaCode[i - 1]).setName(areaName[i]).setParentName(areaName[i - 1]).setClick(false);
                    } else {
                        region.setCode(areaCode[i]).setParentCode(areaCode[i - 1]).setName(areaName[i]).setParentName(areaName[i - 1]).setClick(true);
                    }
                    list.add(region);
                }
                allCode.add(datum.getAllParentCode());
            } else if (areaCode.length == 4) {
                if (allCode.stream().anyMatch(item -> datum.getAllParentCode().startsWith(item))) {
                    continue;
                }
                for (int i = 0; i < areaCode.length; i++) {
                    RegionResponse region = new RegionResponse();
                    if (i == 0) {
                        region.setCode(areaCode[i]).setParentCode("0").setName(areaName[i]).setParentName("").setClick(false);
                    } else if (i == 1) {
                        region.setCode(areaCode[i]).setParentCode(areaCode[i - 1]).setName(areaName[i]).setParentName(areaName[i - 1]).setClick(false);
                    } else {
                        region.setCode(areaCode[i]).setParentCode(areaCode[i - 1]).setName(areaName[i]).setParentName(areaName[i - 1]).setClick(true);
                    }
                    list.add(region);
                }
            }
            allList.addAll(list);
        }
        //TODO 有隐患，如何根据字段值进行去重
        List<RegionResponse> groupCollect = allList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(RegionResponse::getCode))), ArrayList::new));
        List<RegionResponse> collect = groupCollect.stream().filter(item -> !item.getName().contains("政企") && !item.getName().contains("校园") && !item.getName().contains("虚拟网格") && !item.getName().contains("商企网格")).collect(Collectors.toList());
        TreeNodeConfig config = new TreeNodeConfig();
        config.setIdKey("code");                              //默认id，可以不设置
        config.setParentIdKey("parentCode");                       //父id
        config.setNameKey("name");              //分类名称
        config.setChildrenKey("childNode");              //孩子节点
        config.setWeightKey("code");                     //排序字段
        //3.转树
        List<Tree<String>> list = TreeUtil.build(collect, "0", config, ((object, treeNode) -> {
            treeNode.putExtra("code", object.getCode());
            treeNode.putExtra("parentCode", object.getParentCode());
            treeNode.putExtra("name", object.getName());
            treeNode.putExtra("parentName", object.getParentName());
            treeNode.putExtra("isClick", object.isClick());
        }));
        return list;
    }

    @Override
    public List<UniAddrRegion> getGridList(String code) {
        QueryWrapper<UniAddrRegion> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().select(UniAddrRegion::getCode, UniAddrRegion::getName, UniAddrRegion::getParentCode).eq(UniAddrRegion::getParentCode, code);
        return uniAddrRegionService.list(queryWrapper).stream().filter(item -> !item.getName().contains("政企") && !item.getName().contains("校园") && !item.getName().contains("虚拟网格") && !item.getName().contains("商企网格")).sorted(Comparator.comparing(UniAddrRegion::getCode)).collect(Collectors.toList());
    }

    @Override
    public List<Tree<String>> getAppRegionListNew(String regionCode,String regionName,Integer roleType) {
        log.debug("app区域列表查询入参,{},{},{}", regionCode, regionName, roleType);
            if (StringUtils.isEmpty(regionCode) || StringUtils.isEmpty(regionName)){
                return Lists.newArrayList();
            }
            String[] areaCode = regionCode.split(",");
            String[] areaName = regionName.split("-");
            String areaCodeStr = areaCode[areaCode.length-1];
            if (!Objects.equals(areaCode.length, areaName.length)) {
                throw new CommonException("解析接口-区域编码与名称映射出错！");
            }

            List<RegionResponse> list = new ArrayList<>();
            //省角色
            if (RoleCodeEnum.ONE.getCode().equals(roleType)){
                List<UniAddrRegion> uniAddrRegionList = uniAddrRegionService.selectProvinceCityDisList();
                uniAddrRegionList.stream()
                        .filter(region -> region.getCode().equals("SD"))
                        .forEach(region -> {
                            region.setParentCode("0");
                        });
                list = BeanUtil.copyToList(uniAddrRegionList, RegionResponse.class);
            }else if (RoleCodeEnum.TWO.getCode().equals(roleType)){
                List<UniAddrRegion> uniAddrRegionList = uniAddrRegionService.selectRegionByParentCode(areaCodeStr);
                QueryWrapper<UniAddrRegion> sdWrapper = new QueryWrapper<>();
                sdWrapper.lambda().select(UniAddrRegion::getCode, UniAddrRegion::getName, UniAddrRegion::getParentCode).eq(UniAddrRegion::getLevel, 1).ne(UniAddrRegion::getState,-1);
                UniAddrRegion sd = uniAddrRegionService.getBaseMapper().selectOne(sdWrapper);
                RegionResponse sdRegion = new RegionResponse();
                BeanUtils.copyProperties(sd, sdRegion);
                sdRegion.setParentCode("0");
                sdRegion.setClick(false);
                list = BeanUtil.copyToList(uniAddrRegionList, RegionResponse.class);
                list.add(sdRegion);
            } else if (RoleCodeEnum.THREE.getCode().equals(roleType)) {
                for (int index = 0; index < areaCode.length; index++) {
                    RegionResponse region = new RegionResponse();
                    if (index == 0) {
                        region.setCode(areaCode[index]).setParentCode("0").setName(areaName[index]).setParentName("").setClick(false);
                    } else region.setCode(areaCode[index]).setParentCode(areaCode[index - 1]).setName(areaName[index]).setParentName(areaName[index - 1]).setClick(index != 1);
                    list.add(region);
                }
            //网格，渠道，直销，自有都返回网格信息
            }else {
                for (int index = 0; index < areaCode.length; index++) {
                    RegionResponse region = new RegionResponse();
                    if (index == 0) {
                        region.setCode(areaCode[index]).setParentCode("0").setName(areaName[index]).setParentName("").setClick(false);
                    } else region.setCode(areaCode[index]).setParentCode(areaCode[index - 1]).setName(areaName[index]).setParentName(areaName[index - 1]).setClick(false);
                    list.add(region);
                }
            }
            List<RegionResponse> groupCollect = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(RegionResponse::getCode))), ArrayList::new));
            List<RegionResponse> collect = groupCollect.stream().filter(item -> !item.getName().contains("政企") && !item.getName().contains("校园") && !item.getName().contains("虚拟网格") && !item.getName().contains("商企网格")).collect(Collectors.toList());
            TreeNodeConfig config = new TreeNodeConfig();
            config.setIdKey("code");                              //默认id，可以不设置
            config.setParentIdKey("parentCode");                       //父id
            config.setNameKey("name");              //分类名称
            config.setChildrenKey("childNode");              //孩子节点
            config.setWeightKey("code");                     //排序字段
            //3.转树
            return  TreeUtil.build(collect, "0", config, ((object, treeNode) -> {
                treeNode.putExtra("code", object.getCode());
                treeNode.putExtra("parentCode", object.getParentCode());
                treeNode.putExtra("name", object.getName());
                treeNode.putExtra("parentName", object.getParentName());
                treeNode.putExtra("isClick", object.isClick());
            }));
    }
}
